/**
 *
 */
package de.cbf.cam.dsa.rcp.model.entities;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;

import javax.xml.bind.annotation.XmlRootElement;

import de.cbf.util.uuidheader.entities.UUIDHeader;
import de.cbf.util.uuidheader.exceptions.EntityMergeException;

/**
 * @author Surfer
 *
 */
@XmlRootElement(name = "profession")
public class ProfessionDSA extends RCPPerked implements Cloneable {

	/**
	 * if this is not null, than this is sub profession<br>
	 * Sub professions do not hold all data, but masterProfession does<br>
	 * so always check master profession if data is missing
	 * TODO find a place to get all sub professions(by iterating) for a masterProfession
	 */
	protected ProfessionDSA masterProfession;

	protected Map<String, ProfessionLevel> professionLevels;

	public ProfessionDSA() {
		super();
		init();
	}

	protected void init() {
		professionLevels = new HashMap<String, ProfessionLevel>();
	}

	@Override
	protected void doMergeDataFrom(UUIDHeader entity, boolean i_am_older)
			throws EntityMergeException {
		super.doMergeDataFrom(entity, i_am_older);
		if (entity instanceof ProfessionDSA) {
			ProfessionDSA other = (ProfessionDSA) entity;
			if(i_am_older){
				this.professionLevels.clear();
				this.professionLevels.putAll(other.professionLevels);
				this.masterProfession = other.masterProfession;
			}
		}else{
			String mergeEntityClass = entity == null? "null":entity.getClass().getName();
			String errorMsg ="EntityToMerge "+mergeEntityClass+" does not fit class:"+this.getClass().getName();
			throw new EntityMergeException(errorMsg);
		}
	}

	@Override
	public Object clone() throws CloneNotSupportedException {
		ProfessionDSA clone = new  ProfessionDSA();
		try {
			clone.mergeDataFrom(this);
		} catch (EntityMergeException e) {
			throw new CloneNotSupportedException(e.getLocalizedMessage());
		}
		return clone;
	}

	public List<PerkDSA> getWeightedPerks() {
		if(weightedPerks == null && masterProfession != null){
			return masterProfession.getWeightedPerks();
		}
		return weightedPerks;
	}

	public List<ProfessionLevel> getPossibleProfessionLevelsForAge(Integer age){
		if(professionLevels == null && masterProfession != null){
			return masterProfession.getPossibleProfessionLevelsForAge(age);
		}
		List<ProfessionLevel> result = new ArrayList<ProfessionLevel>();
		Set<String> keys = professionLevels.keySet();
		for (String key : keys) {
			ProfessionLevel professionLevel = professionLevels.get(key);
			if(professionLevel.getMinAge() <= age && professionLevel.getMaxAge() >= age){
				result.add(professionLevel);
			}
		}
		return result;
	}

	public Map<String, ProfessionLevel> getProfessionLevels() {
		if(professionLevels == null && masterProfession != null){
			return masterProfession.getProfessionLevels();
		}
		return professionLevels;
	}

	public void setProfessionLevels(Map<String, ProfessionLevel> professionLevels) {
		this.professionLevels = professionLevels;
	}

	public ProfessionDSA getMasterProfession() {
		return masterProfession;
	}

	public void setMasterProfession(ProfessionDSA masterProfession) {
		this.masterProfession = masterProfession;
	}




}
